import Slicer

class Parser:
    UNDEF       = -1
    ACOMMAND    = 0
    CCOMMAND    = 1
    LCOMMAND    = 2
    
    def resetComInfo(self):
        self.comType = self.UNDEF
        self.tokenType = Slicer.PARSER_UNDEFN
        self.symbol = ''
        self.dest = ''
        self.comp = ''
        self.jump = ''
    
    def getComType(self):
        return self.comType
        
    def getTokenType(self):
        return self.tokenType
    
    def getSymbol(self):
        return self.symbol
    
    def getDest(self):
        return self.dest
    
    def getComp(self):
        return self.comp
    
    def getJump(self):
        return self.jump
    
    def __init__(self, file) -> None:
        self.slicer = Slicer.Slicer(file)
        self.resetComInfo()
    
    def hasMoreCommands(self):
        return self.slicer.hasMoreCommands()
    
    def setACommand(self):
        self.comType = self.ACOMMAND
        self.tokenType, self.symbol = self.slicer.toNextToken()
    
    def makeDest(self, token0, valve0):
        token1, valve1 = self.slicer.getNextToken()
        if(token1 == Slicer.PARSER_OPERAT and valve1 == '='):
            self.slicer.toNextToken()
            self.dest = valve0
            tokenx, valvex = self.slicer.toNextToken()
        else:
            tokenx, valvex = token0, valve0
        return (tokenx, valvex)
    
    def makeComp(self, token0, valve0):
        if(token0 == Slicer.PARSER_OPERAT and (valve0 == '-' or valve0 == '!')):
            token1, valve1 = self.slicer.toNextToken()
            self.comp = valve0 + valve1
        elif(token0 == Slicer.PARSER_NUMBER or token0 == Slicer.PARSER_LOCATE):
            self.comp = valve0
            token1, valve1 = self.slicer.getNextToken()
            if(token1 == Slicer.PARSER_OPERAT and valve1 != ';'):
                self.slicer.toNextToken()
                token2, valve2 = self.slicer.toNextToken()
                self.comp += valve1 + valve2
    
    def makeJump(self):
        token0, valve0 = self.slicer.toNextToken()
        if(token0 == Slicer.PARSER_OPERAT and valve0 == ';'):
            token1, valve1 = self.slicer.toNextToken()
            self.jump = valve1
    
    def setCCommand(self, token0, valve0):
        self.comType = self.CCOMMAND
        token1, valve1 = self.makeDest(token0, valve0)
        self.makeComp(token1, valve1)
        self.makeJump()
    
    def setLCommand(self):
        self.comType = self.LCOMMAND
        self.tokenType, self.symbol = self.slicer.toNextToken()
    
    def advance(self):
        self.resetComInfo()
        self.slicer.toNextCommand()
        token, valve = self.slicer.curToken
        if(token == Slicer.PARSER_OPERAT and valve == '@'):
            self.setACommand()
        elif(token == Slicer.PARSER_OPERAT and valve == '('):
            self.setLCommand()
        else:
            self.setCCommand(token, valve)